package com.db.bankapp.domain;

/**
 * Build Client.
 * Client name, sex, account must be provided
 */
public class ClientBuilder {
    private String name;
    private Gender sex;
    private Account account;

    private ClientBuilder(String name) {
        this.name = name;
    }

    /**
     * Initial method
     * @param name of client to create
     * @return this
     * @throws java.lang.IllegalArgumentException when name is null or empty
     */
    public static ClientBuilder newClient(String name) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("invalid name!");
        }
        return new ClientBuilder(name);
    }

    /**
     * Sets female gender to client
     * @return this
     * @throws java.lang.IllegalStateException when sex have already been set
     */
    public ClientBuilder female() {
        checkSex(this.sex);
        this.sex = Gender.FEMALE;
        return this;
    }

    /**
     * Sets male gender to client
     * @return this
     * @throws java.lang.IllegalStateException when sex have already been set
     */
    public ClientBuilder male() {
        checkSex(this.sex);
        this.sex = Gender.MALE;
        return this;
    }

    /**
     * Adds first account to the client
     * @param account to add to the client
     * @return this
     * @throws java.lang.NullPointerException when account is null
     */
    public ClientBuilder withAccount(Account account) {
        if (account == null) {
            throw new NullPointerException("Account should not be null!");
        }
        this.account = account;
        return this;
    }

    /**
     * Terminal method
     * @return client
     * @throws java.lang.IllegalStateException when at least one of name, sex, account is not set
     */
    public Client build() {
        if (name == null || name.isEmpty()) {
            throw new IllegalStateException("Name must be set!");
        }
        if (sex == null) {
            throw new IllegalStateException("Sex must be set!");
        }
        if (account == null) {
            throw new IllegalStateException("Account must be set!");
        }
        return new Client(name, sex, account);
    }

    private static void checkSex(Gender sex) {
        if (sex != null) {
            throw new IllegalStateException("Sex already set!");
        }
    }
}
